﻿<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html>
<!-- saved from url=(0033)http://research.microsoft.com/pex -->
<head><link rel="StyleSheet" href="er.common.css" type="text/css" /><script src="er.common.js" type="text/javascript"> </script><link rel="SHORTCUT ICON" href="favicon.ico" /><link rel="icon" href="favicon.ico" type="image/x-icon" /><title>C:\Users\AO\Documents\Visual Studio 2010\AutomaTones3\automatones\AutomaTones\AutomaTones\Model\Automaton Model\Rule.cs</title></head><body><div class="banner"></div><h2 id="top">C:\Users\AO\Documents\Visual Studio 2010\AutomaTones3\automatones\AutomaTones\AutomaTones\Model\Automaton Model\Rule.cs</h2><div class="toggle"><p class="copyright"><a class="usercodeundertestcovered">user code under test</a>, 
  <span class="usercodeundertestnotcovered">user code under test (not covered)</span>, 
  <a class="userortestcodecovered">user code or test</a>, 
  <span class="userortestcodenotcovered">user code or test (not covered)</span>,
  <span class="tagged">tagged</span></p><table><tr><th>Methods</th></tr><tr><th /></tr></table><div class="toggle"><a class="button" href="#ID0EL">first</a><pre class="coverage">using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Pex.Framework;

namespace AutomaTones.Model.Automaton_Model {
    /// &lt;author&gt;Anders Øland / anoe@itu.dk&lt;/author&gt;
    /// &lt;summary&gt;
    ///   A rule defining how a cell evolves.
    ///   The rule decides a cells next state based on the current state of its neighbours.
    ///   Each rule defines its own neighbourhood.
    ///   The processing is done by a RuleDelegate (which may be a multicast delegate).
    /// &lt;/summary&gt;
    [PexClass]
    [Serializable]
    public class Rule {
        /// &lt;summary&gt;
        ///   The number of dimensions this rule work in; MUST match the dimensions of the automaton.
        /// &lt;/summary&gt;
        protected internal uint Dimensions { get; private set; }

        /// &lt;summary&gt;
        ///   The delegate type used for the methods which perform the actual rule processing.
        /// &lt;/summary&gt;
        /// &lt;param name = "cell"&gt;The cell to be processed&lt;/param&gt;
        /// &lt;param name="statesOfNeighbours"&gt;The states of the cells neighbours&lt;/param&gt;
        /// &lt;param name="optional"&gt;optional parameters for specialized rules&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        public delegate int RuleDelegate(
            Cell cell, ref IEnumerable&lt;StateAtCoordinate&gt; statesOfNeighbours, params int[] optional);

        /// &lt;summary&gt;
        ///   The concrete RuleDelagate used by this Rule to process the next state of a cell
        ///   based on the states of the cells in its neighbourghood.
        /// &lt;/summary&gt;
        public RuleDelegate MyRuleDelegate { get; set; }

        <span id="ID0EL"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EVC">next</a></span><a class="userortestcodecovered">private List&lt;Position&gt; _neighbourhood = new List&lt;Position&gt;();</a>

        /// &lt;summary&gt;
        ///   The coordinates of the neighbouring cells to be used when this rule is applied.
        ///   Subject cell is always [0 ,0] (in a 2-dim. grid.) and eg. the left neighbnour is [-1, 0]
        /// &lt;/summary&gt;
        public List&lt;Position&gt; Neighbourhood {
            get <a class="button" href="#ID0EL">prev</a>|<span id="ID0EVC"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EVE">next</a></span><a class="userortestcodecovered">{</a> <a class="userortestcodecovered">return _neighbourhood;</a> <a class="userortestcodecovered">}</a>
            protected internal set {
                Contract.Requires(null != value);
                Contract.Requires(Contract.ForAll&lt;Position&gt;(value, n =&gt; Dimensions == n.Coord.Length));
                Contract.Ensures(Neighbourhood == value);
                _neighbourhood = value;
            }
        }

        /// &lt;summary&gt;
        ///   For storing coordinates of (neighbouring) cells.
        ///   Explicit conversions to and from int[] are supported.
        /// &lt;/summary&gt;
        [Serializable]
        public struct Position {
            private int[] _coord;

            public int[] Coord {
                get <a class="button" href="#ID0EL">prev</a>|<span id="ID0EVE"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EVG">next</a></span><a class="userortestcodecovered">{</a> <a class="userortestcodecovered">return _coord;</a> <a class="userortestcodecovered">}</a>
                internal set <a class="button" href="#ID0EL">prev</a>|<span id="ID0EVG"><a class="button" href="#top">top</a>|<a class="button" href="#ID0E1AAC">next</a></span><a class="userortestcodecovered">{</a>
                    Contract.Requires(null != value);
                    Contract.Requires(0 &lt; value.Length);
                    Contract.Ensures(_coord.Equals(value));
                    <a class="userortestcodecovered">_coord = value;</a>
                <a class="userortestcodecovered">}</a>
            }

            public Position(params int[] coord)
                : this() {
                Contract.Requires(null != coord);
                Contract.Requires(0 &lt; coord.Length);
                Contract.Ensures(null != coord &amp; this.Coord == coord);
                Coord = coord;
            }

            // explicit conversion from Position to int[], useful for clients.
            public static explicit operator int[](Position p) {
                Contract.Requires(null != p.Coord);
                Contract.Ensures(Contract.ForAll(0, p.Coord.Length,
                                                 i =&gt; p.Coord[i] == Contract.Result&lt;int[]&gt;()[i]));
                return p.Coord.ToArray();
            }

            // explicit conversion from int[] to Position, useful for clients.
            public static explicit operator Position(int[] c) <a class="button" href="#ID0EL">prev</a>|<span id="ID0E1AAC"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EKDAC">next</a></span><a class="userortestcodecovered">{</a>
                Contract.Requires(null != c);
                Contract.Requires(0 &lt; c.Length);
                Contract.Ensures(Contract.ForAll(0, c.Length,
                                                 i =&gt; c[i] == Contract.Result&lt;Position&gt;().Coord[i]));
                <a class="userortestcodecovered">return new Position { Coord = (int[])c.Clone() };</a>
            <a class="userortestcodecovered">}</a>

            /// &lt;summary&gt;
            /// Pracical + operator when deciding actual coordinates of neighbours 
            /// (relative to the subject/center cell) 
            /// &lt;/summary&gt;
            /// &lt;param name="left"&gt;&lt;/param&gt;
            /// &lt;param name="right"&gt;&lt;/param&gt;
            /// &lt;returns&gt;&lt;/returns&gt;
            public static int[] operator +(Position left, int[] right) <a class="button" href="#ID0EL">prev</a>|<span id="ID0EKDAC"><a class="button" href="#top">top</a>|<a class="button" href="#ID0ELJAC">next</a></span><a class="userortestcodecovered">{</a>
                Contract.Requires(left.Coord.Length == right.Length);
                <a class="userortestcodecovered">int[] result = new int[left.Coord.Length];</a>
                for (<a class="userortestcodecovered">int i = 0;</a> <a class="userortestcodecovered">i &lt; right.Length</a>; <a class="userortestcodecovered">i++</a>)
                    <a class="userortestcodecovered">result[i] = right[i] + left.Coord[i];</a>
                <a class="userortestcodecovered">return result;</a>
            <a class="userortestcodecovered">}</a>

            /// &lt;summary&gt;
            ///   Indicates whether this instance and a specified object are equal.
            ///   Accepts int[] as well as Position.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;
            ///   true if &lt;paramref name = "obj" /&gt; is either Position or int[] and represent the same coordinate; otherwise, false.
            /// &lt;/returns&gt;
            /// &lt;param name = "obj"&gt;Another object to compare to. &lt;/param&gt;
            /// &lt;filterpriority&gt;2&lt;/filterpriority&gt;
            public override bool Equals(object obj) {
                Contract.Requires(null != obj);
                Contract.Requires((obj is Position &amp; ((Position)obj).Coord.Length &gt; 0 || (obj is int[] &amp; ((int[])obj).Length &gt; 0)));
                if (!(obj is Position || obj is int[])) return false;
                Position p;
                if (obj is Position) p = (Position)obj;
                else {
                    int[] tmp = (int[])obj;
                    p = (Position)tmp;
                }
                return p.Coord.SequenceEqual(_coord);
            }

            public override int GetHashCode() {
                return (_coord != null ? _coord.GetHashCode() : 0);
            }
        }

        /// &lt;summary&gt;
        /// A state associated with a given coordinate. Intended for use with neighbours and rules.
        /// Thus the coordinate must be relative to point [0,0.., 0] 
        /// &lt;/summary&gt;
        public struct StateAtCoordinate {
            [NonSerialized]
            private Position _position;

            // ReSharper disable MemberHidesStaticFromOuterClass
            public Position Position {
                // ReSharper restore MemberHidesStaticFromOuterClass
                get { return _position; }
                internal set <a class="button" href="#ID0EL">prev</a>|<span id="ID0ELJAC"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EQNAC">next</a></span><a class="userortestcodecovered">{</a>
                    Contract.Requires(0 &lt; value.Coord.Length);
                    Contract.Ensures(_position.Equals(value));
                    <a class="userortestcodecovered">_position = value;</a>
                <a class="userortestcodecovered">}</a>
            }

            public int State { get; internal set; }

            public StateAtCoordinate(Position pos, int state)
                : this() {
                Contract.Requires(0 &lt; pos.Coord.Length);
                Position = pos;
                State = state;
            }
        }

        /// &lt;summary&gt;
        ///   Construct a Rule for a celluar automaton with the given dimensions.
        /// &lt;/summary&gt;
        /// &lt;param name = "dimensions"&gt;&lt;/param&gt;
        /// &lt;param name = "ruleDelegate"&gt;The rule function&lt;/param&gt;
        <a class="userortestcodecovered">public Rule(uint dimensions, RuleDelegate ruleDelegate)</a> <a class="userortestcodecovered">{</a>
            <a class="userortestcodecovered">Dimensions = dimensions;</a>
            <a class="userortestcodecovered">MyRuleDelegate = ruleDelegate;</a>
        <a class="userortestcodecovered">}</a>

        /// &lt;summary&gt;
        ///   Apply the method in the instance's RuleDelegate to the given cell.
        /// &lt;/summary&gt;
        /// &lt;param name="subject"&gt;&lt;/param&gt;
        /// &lt;param name = "cellularAutomaton"&gt;&lt;/param&gt;
        /// &lt;param name="optional"&gt;Optional parameters for specialized rules&lt;/param&gt;
        /// &lt;returns&gt;The next state of the cell based on current state of its neighbourhood&lt;/returns&gt;
        [PexMethod]
        public virtual int ApplyRule(int[] subject, CellularAutomaton cellularAutomaton, params int[] optional) <a class="button" href="#ID0EL">prev</a>|<span id="ID0EQNAC"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EKBAE">next</a></span><a class="userortestcodecovered">{</a>
            Contract.Requires(null != subject);
            Contract.Requires(0 &lt; Neighbourhood.Count);
            Contract.Ensures(cellularAutomaton.GetCell(subject).State.SpaceMin &lt;= Contract.Result&lt;int&gt;());
            Contract.Ensures(cellularAutomaton.GetCell(subject).State.SpaceMax &gt;= Contract.Result&lt;int&gt;());
            <a class="userortestcodecovered">IEnumerable&lt;StateAtCoordinate&gt; statesOfNeighbours =
                (from n in Neighbourhood
                 select </a><a class="button" href="#ID0EL">prev</a>|<span id="ID0EKBAE"><a class="button" href="#top">top</a>|<a class="button" href="#ID0ERGAE">next</a></span><a class="userortestcodecovered">new StateAtCoordinate {
                     Position = (Position)n.Coord,
                     State = cellularAutomaton.GetCell(n + subject).State.CurrentState
                 }</a><a class="userortestcodecovered">);</a>
            <a class="userortestcodecovered">return DispatchToDelegate(cellularAutomaton.GetCell(subject), statesOfNeighbours, optional);</a>
        <a class="userortestcodecovered">}</a>

        /// &lt;summary&gt;
        /// This method provides a simple yet not perfect workaround for enforcing contracts on delegates.
        /// It simply wraps the invocation of the delegate with pre- and postconditions.
        /// The postcondition focuses on validating the immutability of the forwarded data.
        /// Primarily to ensure that if we're dealine with a multicast delegate - 
        /// none of its members screw things up for the others.
        /// &lt;/summary&gt;
        /// &lt;param name="cell"&gt;&lt;/param&gt;
        /// &lt;param name="statesOfNeighbours"&gt;Call by reference so we can check in the postcondition if it has been modified&lt;/param&gt;
        /// &lt;param name="optional"&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        private int DispatchToDelegate(Cell cell, IEnumerable&lt;StateAtCoordinate&gt; statesOfNeighbours,
                                       params int[] optional) <a class="button" href="#ID0EL">prev</a>|<span id="ID0ERGAE"><a class="button" href="#top">top</a>|<a class="button" href="#ID0EFJAE">next</a></span><a class="userortestcodecovered">{</a>
            Contract.Requires(null != cell);
            Contract.Requires(null != cell.State);
            Contract.Requires(0 &lt; Neighbourhood.Count);
            Contract.Requires(Neighbourhood.Count == statesOfNeighbours.Count());
            Contract.Requires(Contract.ForAll(statesOfNeighbours, s =&gt; Dimensions == s.Position.Coord.Length));
            Contract.Ensures(Contract.OldValue(cell) == cell);
            Contract.Ensures(cell.State.SpaceMin &lt;= Contract.Result&lt;int&gt;());
            Contract.Ensures(cell.State.SpaceMax &gt;= Contract.Result&lt;int&gt;());
            <a class="userortestcodecovered">return MyRuleDelegate(cell, ref statesOfNeighbours, optional);</a>
        <a class="userortestcodecovered">}</a>

        /// &lt;summary&gt;
        ///   Clear the neighbourhood for this rule.
        /// &lt;/summary&gt;
        protected internal void ClearNeighbourhood() {
            _neighbourhood = new List&lt;Position&gt;();
        }

        /// &lt;summary&gt;
        ///   Add a neighbour with the gicen coordinats to the neighbourhood.
        ///   Note: if it is already in the neighbourhood it will not be added again.
        /// &lt;/summary&gt;
        /// &lt;param name = "coord"&gt;&lt;/param&gt;
        protected internal void AddNeighbour(params int[] coord) <a class="button" href="#ID0EL">prev</a>|<span id="ID0EFJAE"><a class="button" href="#top">top</a></span><a class="userortestcodecovered">{</a>
            Contract.Requires(Dimensions == coord.Length);
            Contract.Ensures(Neighbourhood.Contains((Position)coord));
            <a class="userortestcodecovered">_neighbourhood.Add((Position)coord);</a>
        <a class="userortestcodecovered">}</a>

        [ContractInvariantMethod]
// ReSharper disable UnusedMember.Local
        private void ObjInvariant() {
// ReSharper restore UnusedMember.Local
            Contract.Invariant(0 &lt; Dimensions);
        }
    }

    /// &lt;author&gt;Anders Øland / anoe@itu.dk&lt;/author&gt;
    /// &lt;summary&gt;
    /// A specialized rule for use with Wolfram Automata - or other pattern-based rule-type CA's.
    /// &lt;/summary&gt;
    [Serializable]
    public class WolframRule : Rule {
        /// &lt;summary&gt;
        /// The Wolfram code for this Wolfram rule.
        /// &lt;/summary&gt;
        public int[] WolframCode { get; internal set; }

        public WolframRule(uint dimensions, RuleDelegate ruleDelegate, int[] wolframCode)
            : base(dimensions, ruleDelegate) {
            WolframCode = wolframCode;
        }

        /// &lt;summary&gt;
        ///   Apply the method in the instance's RuleDelegate to the given cell.
        /// &lt;/summary&gt;
        /// &lt;param name="subject"&gt;&lt;/param&gt;
        /// &lt;param name = "cellularAutomaton"&gt;&lt;/param&gt;
        /// &lt;param name="optional"&gt;Optional parameters for specialized rules&lt;/param&gt;
        /// &lt;returns&gt;The next state of the cell based on current state of its neighbourhood&lt;/returns&gt;
        public override int ApplyRule(int[] subject, CellularAutomaton cellularAutomaton, params int[] optional) {
            return base.ApplyRule(subject, cellularAutomaton, WolframCode);
        }
    }
}</pre></div></div><hr /><table width="100%"><tr><td valign="top"><span class="copyright">Copyright (c) Microsoft Corporation. All rights reserved.</span><br /><span class="button" onclick="copySourceToClipboard()">Copy full source to clipboard</span></td></tr></table><div id="debugdiv"> </div></body></html>